library(readr)
datSat_Air <- read_csv("C:/Users/eduar/Dropbox/ESTUDIOS/Estadística avanzada/PEC3/datSat_Air.csv")
## Rows: 129446 Columns: 21
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr  (5): satisfaction, Gender, Customer_Type, Type_Travel, Class
## dbl (16): id, Age, Distance, Seat_comfort, Food_drink, Gate, Wifi, Ent, Ease...
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Y mostrar los tipos de datos

str(datSat_Air)
## spec_tbl_df [129,446 x 21] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id              : num [1:129446] 58967 28498 28561 63665 62219 ...
##  $ satisfaction    : chr [1:129446] "neutral or dissatisfied" "satisfied" "satisfied" "satisfied" ...
##  $ Gender          : chr [1:129446] "Female" "Female" "Female" "Male" ...
##  $ Customer_Type   : chr [1:129446] "disloyal Customer" "Loyal Customer" "Loyal Customer" "Loyal Customer" ...
##  $ Age             : num [1:129446] 27 63 47 65 59 41 58 39 26 43 ...
##  $ Type_Travel     : chr [1:129446] "Business travel" "Personal Travel" "Business travel" "Business travel" ...
##  $ Class           : chr [1:129446] "Business" "Business" "Eco Plus" "Business" ...
##  $ Distance        : num [1:129446] 2838 2692 2697 3105 4018 ...
##  $ Seat_comfort    : num [1:129446] 2 1 5 5 4 3 2 3 5 1 ...
##  $ Food_drink      : num [1:129446] 2 1 3 2 4 3 4 3 5 1 ...
##  $ Gate            : num [1:129446] 5 1 3 5 3 4 2 3 5 4 ...
##  $ Wifi            : num [1:129446] 3 4 1 4 3 3 4 5 5 4 ...
##  $ Ent             : num [1:129446] 2 4 4 3 4 3 3 3 5 1 ...
##  $ Ease_booking    : num [1:129446] 3 2 5 4 3 3 5 4 5 4 ...
##  $ Service         : num [1:129446] 4 2 5 4 3 2 5 4 1 3 ...
##  $ Baggage_handling: num [1:129446] 5 2 5 4 3 4 5 4 4 4 ...
##  $ Checkin_service : num [1:129446] 4 3 2 3 4 3 4 5 3 2 ...
##  $ Cleanliness     : num [1:129446] 4 2 5 4 3 3 5 4 2 3 ...
##  $ Online_boarding : num [1:129446] 3 4 2 4 3 3 3 5 5 4 ...
##  $ Departure_Delay : num [1:129446] 45 43 41 40 39 39 38 36 34 33 ...
##  $ Arrival_Delay   : num [1:129446] 0 0 0 0 0 0 0 0 0 0 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   satisfaction = col_character(),
##   ..   Gender = col_character(),
##   ..   Customer_Type = col_character(),
##   ..   Age = col_double(),
##   ..   Type_Travel = col_character(),
##   ..   Class = col_character(),
##   ..   Distance = col_double(),
##   ..   Seat_comfort = col_double(),
##   ..   Food_drink = col_double(),
##   ..   Gate = col_double(),
##   ..   Wifi = col_double(),
##   ..   Ent = col_double(),
##   ..   Ease_booking = col_double(),
##   ..   Service = col_double(),
##   ..   Baggage_handling = col_double(),
##   ..   Checkin_service = col_double(),
##   ..   Cleanliness = col_double(),
##   ..   Online_boarding = col_double(),
##   ..   Departure_Delay = col_double(),
##   ..   Arrival_Delay = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Añadimos la nueva variable del enunciado

library("dplyr")
datos_limpios <- datSat_Air

datos_limpios <- datos_limpios %>% 
  mutate(
    satisfaction_re = case_when( 
      satisfaction == "neutral or dissatisfied" ~ 0,
      satisfaction == "satisfied" ~ 1,
      TRUE ~ 0
    )
  )

1 Regresión lineal

1.1 Modelo de regresión lineal (variables cuantitativas)

1.1.1 Variable Arrival_Delay Vs Variable Distance

Diagrama de dispersión entre Arrival_Delay y Distance

ggplot(datos_limpios, aes(x=Arrival_Delay, y=Distance)) + geom_point() + theme_light()

De la figura anterior se ve claramente que a medida que aumenta la distancia, la proporción de retrasos que ella ofrece decrece.

La función lm se aplica con la fórmula Arrival_Delay~ Distance para indicar que precio es la variable respuesta y que maestros es la variable explicativa. Los resultados de la función lm se almacenan en el objeto mod1 para luego poder usar el modelo ajustado. La segunda línea del código mostrado abajo se usa para mostrar por pantalla un reporte sencillo del modelo ajustado.

#Creamos el modelo
mod1 <- lm(Arrival_Delay ~ Distance, data=datos_limpios)
mod1
## 
## Call:
## lm(formula = Arrival_Delay ~ Distance, data = datos_limpios)
## 
## Coefficients:
## (Intercept)     Distance  
##     7.23871      0.00385
#Tabla resumen
summary(mod1)
## 
## Call:
## lm(formula = Arrival_Delay ~ Distance, data = datos_limpios)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -34.00 -15.30 -11.74  -1.29 477.72 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 7.239e+00  2.166e-01   33.42   <2e-16 ***
## Distance    3.850e-03  9.709e-05   39.66   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 35.86 on 129444 degrees of freedom
## Multiple R-squared:  0.012,  Adjusted R-squared:  0.012 
## F-statistic:  1573 on 1 and 129444 DF,  p-value: < 2.2e-16

Con la salida, se puede interpretar que, por cada incremento de distancia, se espera que el tiempo de retraso aumente en 3.850e-03. Por otro lado, si no hay incremento de distancia se espera que el tiempo promedio de retraso sea de 7.239e+00.

Añadimos la recta de regresión que representa el modelo ajustado anterior

ggplot(datos_limpios,  aes(x=Arrival_Delay, y=Distance)) + 
  geom_point() +
  geom_smooth(method='lm', formula=y~x, se=FALSE, col='dodgerblue1') +
  theme_light()

1.1.2 Variable Arrival_Delay Vs Variable Distance Vs Departure_Delay

Diagrama de dispersión entre las variables

plot_ly(x=datos_limpios$Arrival_Delay, y=datos_limpios$Distance, z=datos_limpios$Departure_Delay, type="scatter3d", color=datos_limpios$Arrival_Delay) %>% 
  layout(scene = list(xaxis = list(title = 'Arrival_Delay'),
                      yaxis = list(title = 'Distance'),
                      zaxis = list(title = 'Departure_Delay')))
## No scatter3d mode specifed:
##   Setting the mode to markers
##   Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode

Se añade al modelo la nueva variable

#Creamos el modelo
mod2 <- lm(Arrival_Delay ~ Distance + Departure_Delay, data=datos_limpios)
mod2
## 
## Call:
## lm(formula = Arrival_Delay ~ Distance + Departure_Delay, data = datos_limpios)
## 
## Coefficients:
##     (Intercept)         Distance  Departure_Delay  
##       0.6029844        0.0000953        0.9761408
#Tabla resumen
summary(mod2)
## 
## Call:
## lm(formula = Arrival_Delay ~ Distance + Departure_Delay, data = datos_limpios)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -53.422  -1.951  -0.787  -0.404 236.671 
## 
## Coefficients:
##                  Estimate Std. Error  t value Pr(>|t|)    
## (Intercept)     6.030e-01  6.083e-02    9.913  < 2e-16 ***
## Distance        9.530e-05  2.733e-05    3.487 0.000488 ***
## Departure_Delay 9.761e-01  7.905e-04 1234.821  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.03 on 129443 degrees of freedom
## Multiple R-squared:  0.9227, Adjusted R-squared:  0.9227 
## F-statistic: 7.724e+05 on 2 and 129443 DF,  p-value: < 2.2e-16

Añadimos la recta de regresión que representa el modelo ajustado anterior

mi_3d <- scatterplot3d(x=datos_limpios$Arrival_Delay, y=datos_limpios$Distance, z=datos_limpios$Departure_Delay, pch=1, cex.lab=1,
                       highlight.3d=TRUE, type="h", xlab='Arrival_Delay',ylab='Distance', zlab='Departure_Delay')
mi_3d$plane3d(mod2, lty.box="solid", col='mediumblue')

Con la salida, se puede interpretar que, por cada incremento de distancia, se espera que el tiempo de retraso aumente en 9.530e-05, y por cada incremento de retraso de salida el tiempo de retraso aumente en 9.761e-01. Por otro lado, si no hay incremento de distancia ni incremento en el tiempo de salida se espera que el tiempo promedio de retraso sea de 6.030e-01.

Comparando los dos modelos, nos damos cuenta de que el modelo actual tiene un coeficiente de determinación del 0.9227 mientras que el otro modelo tenía un coeficiente de determinación del 0.012, con estos datos nos damos cuenta que el ultimo modelo es significativamente mejor ya que aporta mayor número de variables al modelo y este se acerca más a 1 (100%) que daría lugar a un buen modelo.

1.2 Modelo de regresión lineal (variables cuantitativas y cualitativas)

1.2.1 Variable Arrival_Delay Vs Variable Distance + Departure_Delay + Service + Food_drink + satisfaction + Customer_Type

#Creamos el modelo
mod3 <- lm(Arrival_Delay ~ Distance + Departure_Delay + Service + Food_drink + satisfaction + Customer_Type, data=datos_limpios)
mod3
## 
## Call:
## lm(formula = Arrival_Delay ~ Distance + Departure_Delay + Service + 
##     Food_drink + satisfaction + Customer_Type, data = datos_limpios)
## 
## Coefficients:
##                 (Intercept)                     Distance  
##                   1.143e+00                    8.383e-05  
##             Departure_Delay                      Service  
##                   9.753e-01                   -6.457e-02  
##                  Food_drink        satisfactionsatisfied  
##                  -2.467e-02                   -7.060e-01  
## Customer_TypeLoyal Customer  
##                   2.137e-01
#Tabla resumen
summary(mod3)
## 
## Call:
## lm(formula = Arrival_Delay ~ Distance + Departure_Delay + Service + 
##     Food_drink + satisfaction + Customer_Type, data = datos_limpios)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -53.770  -2.186  -0.668  -0.194 237.002 
## 
## Coefficients:
##                               Estimate Std. Error  t value Pr(>|t|)    
## (Intercept)                  1.143e+00  1.239e-01    9.227  < 2e-16 ***
## Distance                     8.383e-05  2.733e-05    3.067  0.00216 ** 
## Departure_Delay              9.753e-01  7.922e-04 1231.181  < 2e-16 ***
## Service                     -6.457e-02  2.344e-02   -2.755  0.00588 ** 
## Food_drink                  -2.467e-02  1.945e-02   -1.268  0.20464    
## satisfactionsatisfied       -7.060e-01  6.285e-02  -11.233  < 2e-16 ***
## Customer_TypeLoyal Customer  2.137e-01  7.537e-02    2.836  0.00457 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.03 on 129439 degrees of freedom
## Multiple R-squared:  0.9228, Adjusted R-squared:  0.9228 
## F-statistic: 2.579e+05 on 6 and 129439 DF,  p-value: < 2.2e-16

Nos damos cuenta de que el modelo actual tiene un coeficiente de determinación del 0.9228 casi igual que el modelo anterior. A nivel de variables significativas, nos damos cuenta al observar el P-valor que todas son significativas a excepción de Food_drink que no lo es

#Creamos el modelo
ModelF <- lm(Arrival_Delay ~ Distance + Departure_Delay + Service + satisfaction, data=datos_limpios)

#Tabla resumen
summary(ModelF)
## 
## Call:
## lm(formula = Arrival_Delay ~ Distance + Departure_Delay + Service + 
##     satisfaction, data = datos_limpios)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -53.712  -2.186  -0.643  -0.248 237.063 
## 
## Coefficients:
##                         Estimate Std. Error  t value Pr(>|t|)    
## (Intercept)            1.230e+00  9.910e-02   12.413  < 2e-16 ***
## Distance               8.301e-05  2.733e-05    3.038  0.00239 ** 
## Departure_Delay        9.754e-01  7.921e-04 1231.403  < 2e-16 ***
## Service               -6.577e-02  2.344e-02   -2.806  0.00501 ** 
## satisfactionsatisfied -6.647e-01  5.997e-02  -11.085  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.03 on 129441 degrees of freedom
## Multiple R-squared:  0.9228, Adjusted R-squared:  0.9228 
## F-statistic: 3.868e+05 on 4 and 129441 DF,  p-value: < 2.2e-16

Al crear este nuevo modelo, solamente con las variables significativas nos damos cuenta de que la variable omitida no era necesaria ya que el coeficiente de determinación es el mismo que el modelo anterior.

1.2.2 colinealidad del modelo ModelF

Para comprobar la colinealidad de dicho modelo se va a crear las correlaciones que existen entre la variables de dicho modelo

#Copiamos los datos en un nuevo data frame

Distance <- datos_limpios$Distance
Departure_Delay <- datos_limpios$Departure_Delay
Service <- datos_limpios$Service
satisfaction_re <- datos_limpios$satisfaction_re #se añade la nueva variable creada antes para poder aplicar la correlacion de esta variable

datos_ModelF<-data.frame(Distance,Departure_Delay,Service,satisfaction_re)

#Calculamos la correlaciones
correlacion <- cor(datos_ModelF)
correlacion
##                    Distance Departure_Delay     Service satisfaction_re
## Distance         1.00000000      0.11127085 -0.03233923     -0.03901325
## Departure_Delay  0.11127085      1.00000000 -0.03868295     -0.07586039
## Service         -0.03233923     -0.03868295  1.00000000      0.35234002
## satisfaction_re -0.03901325     -0.07586039  0.35234002      1.00000000
corrplot(correlacion, method = "pie")

Aunque a simple viste no existe mucha correlación entre las variables, para asegurarnos calcularemos el VIF del modelo

vif_values <- vif(ModelF)
vif_values
##        Distance Departure_Delay         Service    satisfaction 
##        1.013852        1.017933        1.142322        1.147393

Tras ver el resultado, nos damos que no existe colinealidad en dicho modelo.

1.3 Diagnosis del modelo

Analizamos los residuos del modelo

confint(ModelF)
##                               2.5 %        97.5 %
## (Intercept)            1.035881e+00  1.4243355220
## Distance               2.944965e-05  0.0001365771
## Departure_Delay        9.738296e-01  0.9769345900
## Service               -1.117061e-01 -0.0198338204
## satisfactionsatisfied -7.822809e-01 -0.5472101111
influencePlot(ModelF)

##          StudRes          Hat        CookD
## 129285 21.065079 0.0001137094 0.0100581712
## 129360 23.698808 0.0001451703 0.0162385376
## 129363 20.948729 0.0002519579 0.0220453069
## 129403 20.786891 0.0002700866 0.0232694125
## 129439 -3.359354 0.0017207363 0.0038901756
## 129442 -0.698095 0.0015338633 0.0001497318

Con este grafico y su salida, nos damos cuenta de que tenemos 6 datos atípicos.

Relación lineal entre los predictores numéricos y la variable dependiente:

ggplot(data = datos_limpios, aes(x = Arrival_Delay, y = ModelF$residuals)) +
geom_point() +
geom_smooth(color = "firebrick") +
geom_hline(yintercept = 0) +
theme_bw()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

Se satisface la condición de linealidad.

Distribución normal de los residuos:

qqnorm(ModelF$residuals)
qqline(ModelF$residuals)

La condición de normalidad se satisface.

Variabilidad constante de los residuos:

ggplot(data = data.frame(predict_values = predict(ModelF),
                         residuos = residuals(ModelF)),
       aes(x = predict_values, y = residuos)) +
    geom_point() +
    geom_smooth(color = "firebrick", se = FALSE) +
    geom_hline(yintercept = 0) +
    theme_bw()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

Se satisface la variabilidad constante

1.4 Predicción del modelo

datos <- data.frame(Distance=2500,
                    Departure_Delay=30,
                    Service=3,
                    satisfaction="satisfied")
cat('El retraso previsto según las caracteristicas introducidos es de:', predict(object=ModelF, newdata=datos), 'minutos.')
## El retraso previsto según las caracteristicas introducidos es de: 29.83705 minutos.

2 Regresión logística

Hacemos una copia de los datos originales y creamos la nueva variable

datos_RL <- datSat_Air

library("dplyr")

datos_RL <- datos_RL %>% 
  mutate(
    satisfaction_re = case_when( 
      satisfaction == "neutral or dissatisfied" ~ 0,
      satisfaction == "satisfied" ~ 1,
      TRUE ~ 0
    )
  )

2.1 Generación de los conjuntos de entrenamiento y de test

set.seed(1000)
traindataset <- createDataPartition(datos_RL$satisfaction_re, p=0.8, list = FALSE)
testdf <- datos_RL[-traindataset,]

2.2 Estimación del modelo con el conjunto de entrenamiento e interpretación

###Estimación el modelo de regresión logística

logitmodel <- glm(satisfaction_re ~ Gender + Customer_Type + Age + Type_Travel + Class + Distance + Seat_comfort + Food_drink + Gate + Wifi + Ent + Ease_booking + Service + Baggage_handling + Cleanliness + Online_boarding + Departure_Delay + Arrival_Delay, data = datos_RL[traindataset,], family = binomial)

summary(logitmodel)
## 
## Call:
## glm(formula = satisfaction_re ~ Gender + Customer_Type + Age + 
##     Type_Travel + Class + Distance + Seat_comfort + Food_drink + 
##     Gate + Wifi + Ent + Ease_booking + Service + Baggage_handling + 
##     Cleanliness + Online_boarding + Departure_Delay + Arrival_Delay, 
##     family = binomial, data = datos_RL[traindataset, ])
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -3.0348  -0.6020   0.2151   0.5559   3.5446  
## 
## Coefficients:
##                               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                 -5.742e+00  6.775e-02 -84.761  < 2e-16 ***
## GenderMale                  -1.004e+00  1.800e-02 -55.804  < 2e-16 ***
## Customer_TypeLoyal Customer  1.828e+00  2.699e-02  67.732  < 2e-16 ***
## Age                         -6.531e-03  6.230e-04 -10.484  < 2e-16 ***
## Type_TravelPersonal Travel  -7.339e-01  2.534e-02 -28.967  < 2e-16 ***
## ClassEco                    -8.198e-01  2.333e-02 -35.136  < 2e-16 ***
## ClassEco Plus               -9.448e-01  3.579e-02 -26.400  < 2e-16 ***
## Distance                    -1.158e-04  9.375e-06 -12.348  < 2e-16 ***
## Seat_comfort                 2.615e-01  9.956e-03  26.262  < 2e-16 ***
## Food_drink                  -2.920e-01  9.897e-03 -29.502  < 2e-16 ***
## Gate                         3.532e-02  7.921e-03   4.460 8.20e-06 ***
## Wifi                        -7.254e-02  9.528e-03  -7.613 2.67e-14 ***
## Ent                          7.542e-01  8.761e-03  86.087  < 2e-16 ***
## Ease_booking                 2.410e-01  1.190e-02  20.248  < 2e-16 ***
## Service                      3.630e-01  8.990e-03  40.380  < 2e-16 ***
## Baggage_handling             1.575e-01  1.014e-02  15.530  < 2e-16 ***
## Cleanliness                  1.374e-01  1.049e-02  13.097  < 2e-16 ***
## Online_boarding              2.342e-01  1.034e-02  22.644  < 2e-16 ***
## Departure_Delay              3.310e-03  8.815e-04   3.755 0.000173 ***
## Arrival_Delay               -8.398e-03  8.686e-04  -9.668  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 142618  on 103556  degrees of freedom
## Residual deviance:  82960  on 103537  degrees of freedom
## AIC: 83000
## 
## Number of Fisher Scoring iterations: 5

2.2.1 colinealidad del modelo

Para comprobar la colinealidad de dicho modelo se va a comprobar con la función VIF

vif_values_logi <- vif(logitmodel)
vif_values_logi
##                       GVIF Df GVIF^(1/(2*Df))
## Gender            1.063977  1        1.031493
## Customer_Type     1.453155  1        1.205469
## Age               1.223236  1        1.106000
## Type_Travel       1.925943  1        1.387783
## Class             1.679691  2        1.138433
## Distance          1.195917  1        1.093580
## Seat_comfort      2.240864  1        1.496951
## Food_drink        2.529883  1        1.590561
## Gate              1.401018  1        1.183646
## Wifi              1.971601  1        1.404137
## Ent               1.409170  1        1.187085
## Ease_booking      2.794630  1        1.671715
## Service           1.580663  1        1.257244
## Baggage_handling  1.797654  1        1.340766
## Cleanliness       1.919062  1        1.385302
## Online_boarding   2.210489  1        1.486771
## Departure_Delay  13.037144  1        3.610699
## Arrival_Delay    13.054321  1        3.613076

Tras ver el resultado, nos damos que si existe colinealidad en algunas variables, ya que tienen un valor GVIF por encima de 4

2.2.2 Creación del modelo ModlgF

Para la selección de las variables, solamente cogeremos las que tengan un GVIF inferior a 4

ModlgF <- glm(satisfaction_re ~ Gender + Customer_Type + Age + Type_Travel + Class + Distance + Seat_comfort + Food_drink + Gate + Wifi + Ent + Ease_booking + Service + Baggage_handling + Cleanliness + Online_boarding, data = datos_RL[traindataset,], family = binomial)

summary(ModlgF)
## 
## Call:
## glm(formula = satisfaction_re ~ Gender + Customer_Type + Age + 
##     Type_Travel + Class + Distance + Seat_comfort + Food_drink + 
##     Gate + Wifi + Ent + Ease_booking + Service + Baggage_handling + 
##     Cleanliness + Online_boarding, family = binomial, data = datos_RL[traindataset, 
##     ])
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -3.0500  -0.6049   0.2206   0.5603   3.5833  
## 
## Coefficients:
##                               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                 -5.764e+00  6.759e-02 -85.279  < 2e-16 ***
## GenderMale                  -9.906e-01  1.792e-02 -55.288  < 2e-16 ***
## Customer_TypeLoyal Customer  1.816e+00  2.691e-02  67.487  < 2e-16 ***
## Age                         -6.834e-03  6.209e-04 -11.006  < 2e-16 ***
## Type_TravelPersonal Travel  -7.226e-01  2.525e-02 -28.613  < 2e-16 ***
## ClassEco                    -8.310e-01  2.326e-02 -35.721  < 2e-16 ***
## ClassEco Plus               -9.558e-01  3.568e-02 -26.790  < 2e-16 ***
## Distance                    -1.408e-04  9.277e-06 -15.182  < 2e-16 ***
## Seat_comfort                 2.625e-01  9.921e-03  26.456  < 2e-16 ***
## Food_drink                  -2.846e-01  9.848e-03 -28.896  < 2e-16 ***
## Gate                         3.138e-02  7.896e-03   3.974 7.05e-05 ***
## Wifi                        -6.296e-02  9.454e-03  -6.659 2.75e-11 ***
## Ent                          7.493e-01  8.707e-03  86.059  < 2e-16 ***
## Ease_booking                 2.409e-01  1.183e-02  20.369  < 2e-16 ***
## Service                      3.619e-01  8.966e-03  40.363  < 2e-16 ***
## Baggage_handling             1.473e-01  1.011e-02  14.566  < 2e-16 ***
## Cleanliness                  1.502e-01  1.043e-02  14.390  < 2e-16 ***
## Online_boarding              2.265e-01  1.026e-02  22.082  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 142618  on 103556  degrees of freedom
## Residual deviance:  83456  on 103539  degrees of freedom
## AIC: 83492
## 
## Number of Fisher Scoring iterations: 5

Nos damos cuenta de que todas las variables excepto Gate y Wifi tiene influencia similar al tener el mismo p-value. Respecto a las otras dos, tienen un valor mas grande que las otras, pero con bastante influencia.

Referente al tipo de variables, como toda se encuentran por encima de 1, podemos decir que son variables de riesgos.

2.3 Cálculo de las OR (Odds-Ratio)

los odds asociados de las variables explicativas:

exp(ModlgF$coefficients)
##                 (Intercept)                  GenderMale 
##                 0.003139427                 0.371360569 
## Customer_TypeLoyal Customer                         Age 
##                 6.147026042                 0.993189589 
##  Type_TravelPersonal Travel                    ClassEco 
##                 0.485474961                 0.435630937 
##               ClassEco Plus                    Distance 
##                 0.384505046                 0.999859169 
##                Seat_comfort                  Food_drink 
##                 1.300138713                 0.752336438 
##                        Gate                        Wifi 
##                 1.031880402                 0.938980098 
##                         Ent                Ease_booking 
##                 2.115615682                 1.272414007 
##                     Service            Baggage_handling 
##                 1.436026073                 1.158643696 
##                 Cleanliness             Online_boarding 
##                 1.162019136                 1.254252108

Los intervalos de confianza del 95% de las variables son:

confint.default(ModlgF)
##                                     2.5 %        97.5 %
## (Intercept)                 -5.8961823966 -5.6312474810
## GenderMale                  -1.0256979731 -0.9554656342
## Customer_TypeLoyal Customer  1.7632287918  1.8687079972
## Age                         -0.0080506294 -0.0056167850
## Type_TravelPersonal Travel  -0.7721261551 -0.6731289765
## ClassEco                    -0.8765532151 -0.7853665218
## ClassEco Plus               -1.0257257714 -0.8858709597
## Distance                    -0.0001590229 -0.0001226583
## Seat_comfort                 0.2430257807  0.2819161408
## Food_drink                  -0.3038738108 -0.2652695172
## Gate                         0.0159067545  0.0468587863
## Wifi                        -0.0814912206 -0.0444307701
## Ent                          0.7322797492  0.7664119959
## Ease_booking                 0.2177347246  0.2640970530
## Service                      0.3443075095  0.3794517450
## Baggage_handling             0.1274365410  0.1670636467
## Cleanliness                  0.1297069450  0.1706113071
## Online_boarding              0.2064318658  0.2466470638
cat ('Si cambiamos el Gender, la satisfacción cambia en un:', exp(ModlgF$coefficients[2]), '\n')
## Si cambiamos el Gender, la satisfacción cambia en un: 0.3713606
cat ('Si cambiamos el Customer_Type, la satisfacción cambia en un:', exp(ModlgF$coefficients[3]), '\n')
## Si cambiamos el Customer_Type, la satisfacción cambia en un: 6.147026
cat ('Si cambiamos el tipo de Ent, la satisfacción cambia en un:', exp(ModlgF$coefficients[13]), '\n')
## Si cambiamos el tipo de Ent, la satisfacción cambia en un: 2.115616
cat ('Si cambiamos la  Class Eco, la satisfacción cambia en un:', exp(ModlgF$coefficients[6]), '\n')
## Si cambiamos la  Class Eco, la satisfacción cambia en un: 0.4356309
cat ('Si cambiamos la Class Plus, la satisfacción cambia en un:', exp(ModlgF$coefficients[7]), '\n')
## Si cambiamos la Class Plus, la satisfacción cambia en un: 0.384505

2.4 Matriz de confusión

Creamos la matriz de confusión de los datos de test

testdataset <- testdf

predicted_value <- predict(ModlgF,newdata = testdataset,type = "response")
predicted_class <- ifelse(predicted_value>=0.5, 1,0)
performance_data<-data.frame(observed=testdataset$satisfaction_re,predicted= predicted_class)
positive <- sum(performance_data$observed==1)
negative <- sum(performance_data$observed==0)
predicted_positive <- sum(performance_data$predicted==1)
predicted_negative <- sum(performance_data$predicted==0)
total <- nrow(performance_data)
data.frame(positive, negative,predicted_positive,predicted_negative)
##   positive negative predicted_positive predicted_negative
## 1    14155    11734              14294              11595

Calculamos la distribución de Falsos Positivos, Falsos negativos …

tp<-sum(performance_data$observed==1 & performance_data$predicted==1)
tn<-sum(performance_data$observed==0 & performance_data$predicted==0)
fp<-sum(performance_data$observed==0 & performance_data$predicted==1)
fn<-sum(performance_data$observed==1 & performance_data$predicted==0)
data.frame(tp,tn,fp,fn)
##      tp   tn   fp   fn
## 1 12044 9484 2250 2111

Analizamos los resultados con distintas medidas

accuracy <- (tp+tn)/total
error_rate <- (fp+fn)/total
sensitivity <- tp/positive
especificity <- tn/negative
precision <- tp/predicted_positive
npv <- tn / predicted_negative
data.frame(accuracy,error_rate,sensitivity,especificity,precision,npv)
##    accuracy error_rate sensitivity especificity precision       npv
## 1 0.8315501  0.1684499   0.8508654    0.8082495 0.8425913 0.8179388

Entre los resultados de las medias obtenidas, podemos destacar que el nivel de precisión del modelo es del 84,38%. Respecto a la sensibilidad un 84,7% siendo bastante alto el nivel de predicción de positivos.

Por otro lado, la identificación de verdaderos negativos o especificidad es del 80,85%, también siendo un valor bastante alto del modelo de predicción.

2.5 Predicción

datos_pred <- datos_RL[3,]
prob_nuevo <- predict(ModlgF, datos_pred, type="response")
cat('La probabilidad de que el cliente encuestado número tres estuviera satisfecho con la aerolínea es del',  prob_nuevo*100 , '%'  )
## La probabilidad de que el cliente encuestado número tres estuviera satisfecho con la aerolínea es del 94.4629 %

2.6 Bondad del ajuste

2.6.1 Devianza

modelo.null <- glm(satisfaction_re ~ 1,data = datos_RL[traindataset,], family = binomial)
anova(modelo.null, ModlgF)
## Analysis of Deviance Table
## 
## Model 1: satisfaction_re ~ 1
## Model 2: satisfaction_re ~ Gender + Customer_Type + Age + Type_Travel + 
##     Class + Distance + Seat_comfort + Food_drink + Gate + Wifi + 
##     Ent + Ease_booking + Service + Baggage_handling + Cleanliness + 
##     Online_boarding
##   Resid. Df Resid. Dev Df Deviance
## 1    103556     142618            
## 2    103539      83456 17    59162

Como se puede comprobar la devianza residual es menor que la devianza nula.

2.6.2 Chi-cuadrado

dev <- ModlgF$deviance
nullDev <- ModlgF$null.deviance
modelChi <- nullDev - dev
cat('El valor de Chi-cuadrado es: ', modelChi , ' al ser distinto a 0, se rechaza la hipótesis  nula' )
## El valor de Chi-cuadrado es:  59161.8  al ser distinto a 0, se rechaza la hipótesis  nula
chigl <- ModlgF$df.null - ModlgF$df.residual
chisq.prob <- 1 - pchisq(modelChi, chigl)

cat('La probabilidad asociada al estadístico es: ', chisq.prob , ',como la probabilidad es menor que 0.05, podemos rechazar la hipótesis nula' )
## La probabilidad asociada al estadístico es:  0 ,como la probabilidad es menor que 0.05, podemos rechazar la hipótesis nula

2.7 Curva ROC

glm_response_scores <- predict(ModlgF, testdf, type = "response")
roc_obj <- roc(performance_data$observed, performance_data$predicted)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
auc(roc_obj)
plot(roc(performance_data$observed, glm_response_scores), col="blue", lwd=3, main="Curva ROC de ModlgF")
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases

Las curvas ROC se utilizan para analizar como de bien nuestro modelo separa casos positivos de negativos y para identificar el umbral más adecuado. El area de la curva ROC para este modelo es de 0.8278, lo que se aproxima mas a 1 que a 0,5 por lo que se trata de un buen modelo.

3 Informe Ejecutivo

3.1 Presentación de los principales resultados del estudio en una tabla

Modelo Regresión Apartado Observaciones
RL: Arrival_Delay ~ Distance 1.1 Modelo con un coeficiente de determinación del 1,2% en donde si no hay incremento de distancia se espera que el tiempo promedio de retraso sea de 7.239 minutos
RL: Arrival_Delay ~ Distance + Departure_Delay 1.1 Modelo con un coeficiente de determinación del 92,2% lo que lo convierte en un buen modelo
RL: ModelF ~ Distance + Departure_Delay + Service + satisfaction + Customer_Type 1.2 Modelo con un coeficiente de determinación del 92,28% inicialmente tenia más variables, pero tras comprobar la colinealidad se han descartdo algunas
RL: ModelF 1.2 Modelo con un coeficiente de determinación del 92,28% inicialmente tenia más variables, pero tras comprobar la colinealidad se han descartdo algunas
RL: ModelF 1.3 Con el diagnóstico del modelo vemos que tenemos 6 valores atípicos, pero satisface la condición de linealidad y normalidad
RL: ModelF 1.4 El modelo ha predicho que si con una distancia de 2500 millas, con un tiempo de retraso de 30 minutos, una calidad del servicio puntuado con un 3 el retraso será de 29,83 minutos
ModlgF: satisfaction_re ~ Gender + Customer_Type + Age + Type_Travel + Class + Distance + Seat_comfort + Food_drink + Gate + Wifi + Ent + Ease_booking + Service + Baggage_handling + Cleanliness + Online_boarding 2.2 El modelo inicial se ha hecho con todas las variables, pero tras comprobar la colinealidad se han quitado dos de ellas ( Departure_Delay y Arrival_Delay)
ModlgF 2.4 Entre los resultados de las medias obtenidas, podemos destacar que el nivel de precisión del modelo es del 84,38%. Respecto a la sensibilidad un 84,7% siendo bastante alto el nivel de predicción de positivos. Por otro lado, la identificación de verdaderos negativos o especificidad es del 80,85%, también siendo un valor bastante alto del modelo de predicción
ModlgF 2.6 La bondad de ajuste con la Devianza y chi-cuadrado ha descartado la hipótesis nula
ModlgF 2.7 El valor de la curva ROC es 0.8278, al estar por encima de 0.5 y muy cercano a 1 se ve que es un buen modelo

3.2 Resúmen ejecutivo. Conclusiones del análisis

En este estudio sobre regresión lineal y logística, se han creado dos modelos finales, uno para cada tipo, aunque para llegar a estos se ha realizado varias pruebas con otros modelos intermedios.

Si nos centramos en los modelos de regresión lineal, donde se quería comprobar la relación del resto de variables con que un avión llegue con retraso, se ha creado un primer modelo, en donde se enfrentaba el tiempo de retraso con la distancia que recorre el avión, dicho modelo tenia un coeficiente de determinación del 1,2% y en donde si no hay incremento de distancia se espera que el tiempo promedio de retraso sea de 7.239 minutos, pero al tener un coeficiente muy bajo significa que se necesitaba añadir más variables.

En el segundo modelo de regresión lineal, se ha añadido a las variables de antes la variable Departure_Delay, donde se ha aumentado el coeficiente de determinación a un 92,2%, pero al tener 21 variables y solo usar 3, se ha querido crear otro modelo llamado ModelF en la que después de comprobar colinealidad de algunas de sus variables se ha quedado con las siguientes: Distance, Departure_Delay, Service, satisfaction y Customer_Type. Este modelo, tiene un coeficiente de determinación del 92,28% y tras añadir valores a los parámetros, se ha hecho una estimación del tiempo de retraso que tiene un avión según el valor de las otra variables.

Si ahora nos centramos en el modelo de regresión logística, se ha añadido una variable llamada satisfaction_re obtenida a partir de la variable satisfaction, dicha variable será el campo objetivo de la predicción que se quiere obtener.

El modelo, llamado ModlgF inicialmente tenia todas la variables, pero tras ver la colinealidad de la variables, se han descartado Departure_Delay y Arrival_Delay por tener un GVIF superior a 10.

ModlgF tiene un nivel de precisión del modelo es del 84,38%. Respecto a la sensibilidad un 84,7% y respecto a la identificación de verdaderos negativos o especificidad es del 80,85%, lo que lo convierte en un buen modelo de predicción.